from datetime import datetime

from settings import settings
from common.base.base_handler import BaseHandler
from services.server_integration.api import ServerIntegrationApi
from services.server_integration.schemas.alarms import TotalAlarmsCount
from services.server_integration.schemas.alarms_request import AlarmsRequest
from services.server_integration.schemas.cities_timezone import TimezonesRequest
from services.new_services.new_server_integration.schemas.time_gps import GpsTime
from services.new_services.new_server_integration.model import NewServerIntegration
from services.new_services.new_server_integration.schemas.block_info import BlockInfoRequest
from services.new_services.new_server_integration.schemas.alarms_request import NewAlarmsRequest
from services.new_services.new_server_integration.schemas.alarm_configuration import DeleteAlarms
from services.new_services.new_server_integration.schemas.response_message import ResponseMessage
from services.server_integration.schemas.alarms_response_configuration import AlarmResponseConfiguration
from services.new_services.new_server_integration.schemas.short_block_info import ShortBlockInfoResponse
from services.new_services.new_server_integration.schemas.enable_configuration import LinksConnectionType
from services.new_services.new_server_integration.schemas.cities_timezones import ru_timezones, en_timezones
from services.new_services.new_server_integration.schemas.cviya_configuration import AvailableConnectionRequest
from services.new_services.new_server_integration.schemas.full_unit_configuration import NewFullUnitConfiguration
from services.new_services.new_server_integration.schemas.change_block_mode_configuration import ChangeBlockModeRequest


class NewServerIntegrationHandler(BaseHandler):
    SI_API = ServerIntegrationApi()

    __slots__ = ['model']

    async def handle_upload_configuration(self, params: dict) -> ResponseMessage:
        config, user_role = NewFullUnitConfiguration(**params['config']), params['user_role']
        return await self.model.upload_configuration(config, user_role)

    async def handle_get_cities_timezones(self, params: dict):
        request = TimezonesRequest(**params['request'])
        if request.language == 'ru':
            return ru_timezones
        else:
            return en_timezones

    async def handle_change_block_mode(self, params: dict) -> bool:
        block_mode_object = ChangeBlockModeRequest(**params['config'])
        return await self.model.change_block_mode(block_mode_object.block_mode)

    async def handle_enable_radio_or_optics(self, params: dict):
        config, user_role = LinksConnectionType(**params['config']), params['user_role']
        return self.model.enable_radio_or_optics(config, user_role)

    async def handle_get_block_info(self, params: dict) -> ShortBlockInfoResponse:
        config = BlockInfoRequest(**params['config'])
        return await self.model.get_block_info(config.user_role, config.language)

    async def handle_get_log_alarms(self, params: dict):
        request, user_role = NewAlarmsRequest(**params['request']), params['user_role']
        return await self.model.get_log_alarms(request, user_role)

    async def handle_get_current_alarms(self, params: dict):
        request, user_role = NewAlarmsRequest(**params['request']), params['user_role']
        result = await self.model.get_current_alarms(request, user_role)
        return result

    async def handle_get_subblocks_statuses(self):
        return await self.model.get_subblocks_statuses()

    async def handle_get_telemetry(self, params: dict):
        user_role = params['user_role']
        return await self.model.get_telemetry(user_role)

    async def handle_get_available_connection(self, params: dict):
        config = AvailableConnectionRequest(**params['config'])
        return self.model.get_available_connection(config.block_cviya)

    async def handle_get_total_log_alarms(self, params: dict):
        request, user_role = AlarmsRequest(**params['request']), params['user_role']
        request.end_date = datetime(year=2036, month=1, day=1)
        request.filters = []

        result: AlarmResponseConfiguration = AlarmResponseConfiguration(**(await self.SI_API.get_alarms_log(request, user_role)))

        return TotalAlarmsCount(alarms_total_count=result.total_alarms_count,
                                warnings_total_count=result.total_warnings_count)

    async def handle_get_current_total_alarms(self, params: dict):
        request, user_role = AlarmsRequest(**params['request']), params['user_role']
        request.end_date = datetime(year=2036, month=1, day=1)
        result: AlarmResponseConfiguration = AlarmResponseConfiguration(**(await self.SI_API.get_current_alarms(request, user_role)))

        return TotalAlarmsCount(alarms_total_count=result.total_alarms_count,
                                warnings_total_count=result.total_warnings_count)

    async def handle_get_block_version(self):
        return await self.model.get_block_version()

    async def handle_set_new_full_configuration(self, params: dict) -> ResponseMessage:
        config, user_role = params['config'], params['user_role']
        return await self.model.set_new_full_unit_config(config, user_role)

    async def handle_get_new_full_configuration(self):
        return await self.model.get_new_full_unit_config()

    async def handle_get_gps_time(self):
        return await self.model.get_gps_time()

    async def handle_set_gps_time(self, params: dict):
        gps_time: GpsTime = GpsTime(**params['gps_time'])
        return await self.model.set_gps_time(gps_time)

    async def handle_delete_alarms(self, params: dict) -> ResponseMessage:
        alarms_to_be_deleted: DeleteAlarms = DeleteAlarms(**params['alarms_to_be_deleted'])
        return self.model.delete_alarms(alarms_to_be_deleted)

    def __init__(self) -> None:
        self.model = NewServerIntegration()

        super(NewServerIntegrationHandler, self).__init__(
            request_queue_uuid=settings.NEW_SERVER_INTEGRATION_ROUTER_REQUEST_QUEUE
        )

        self.handle('upload_configuration', self.handle_upload_configuration)
        self.handle('get_cities_timezones', self.handle_get_cities_timezones)
        self.handle('enable_radio_or_optics', self.handle_enable_radio_or_optics)
        self.handle('get_log_alarms', self.handle_get_log_alarms)
        self.handle('get_current_alarms', self.handle_get_current_alarms)
        self.handle('get_subblocks_statuses', self.handle_get_subblocks_statuses)
        self.handle('delete_alarms', self.handle_delete_alarms)

        self.handle('get_telemetry', self.handle_get_telemetry)

        self.handle('get_available_connection', self.handle_get_available_connection)
        self.handle('get_block_info', self.handle_get_block_info)
        self.handle('get_total_log_alarms', self.handle_get_total_log_alarms)
        self.handle('get_current_total_alarms', self.handle_get_current_total_alarms)
        self.handle('get_block_version', self.handle_get_block_version)
        self.handle('change_block_mode', self.handle_change_block_mode)

        self.handle('set_new_full_configuration', self.handle_set_new_full_configuration)
        self.handle('get_new_full_configuration', self.handle_get_new_full_configuration)

        self.handle('set_gps_time', self.handle_set_gps_time)
        self.handle('get_gps_time', self.handle_get_gps_time)
